package org.bbelovic.devel.exercises.collatz.gui;

import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

import org.bbelovic.devel.exercises.collatz.Axis;
import org.bbelovic.devel.exercises.collatz.AxisConfiguration;
import org.bbelovic.devel.exercises.collatz.AxisConfigurator;
import org.bbelovic.devel.exercises.collatz.CollatzProblem;

public class DrawPanel extends JPanel {

    private static final long serialVersionUID = -1053313686201284549L;

    @Override
    public void paintComponent(Graphics g) {
        final List<Point> inputData = computeCollatzValues(3);

        final AxisConfiguration configuration = prepareConfiguration(inputData);
        final Axis axis = new Axis(configuration);
        axis.drawAxes(g);
        

        for (Point eachPoint: inputData) {
            axis.drawPoint(eachPoint, g);
        }
    }

    private double maxX(List<Point> points) {
        double result = Double.NEGATIVE_INFINITY;
        for (final Point eachPoint: points) {
            if (eachPoint.getX() > result) {
                result = eachPoint.getX();
            }
        }
        return result;
    }
    
    private double maxY(List<Point> points) {
        double result = Double.NEGATIVE_INFINITY;
        for (final Point eachPoint: points) {
            if (eachPoint.getY() > result) {
                result = eachPoint.getY();
            }
        }
        return result;
    }
    
    private List<Point> computeCollatzValues(final int n) {
        final CollatzProblem collatz = new CollatzProblem();
        List<Integer> values = collatz.computeCollatzNumbers(n);
        List<Point> result = new ArrayList<Point>();
        for (int i = 0; i < values.size(); i++) {
            Point p = new Point((i+1), values.get(i));
            result.add(p);
        }
        return result;
    }
    
    private AxisConfiguration prepareConfiguration(final List<Point> inputData) {
        double maxX = maxX(inputData);
        double maxY = maxY(inputData);
        AxisConfigurator ac = new AxisConfigurator(240, (int)maxX);
        final int xSize = ac.computeSteps();
        final int xScaleStep = ac.computeScaleStep();
        ac = new AxisConfigurator(240, (int)maxY);
        final int ySize = ac.computeSteps();
        final int yScaleStep = ac.computeScaleStep();
        final AxisConfiguration configuration = new AxisConfiguration.AxisConfigurationBuilder().
                height(getHeight())
               .width(getWidth())
               .xScale(xSize)
               .yScale(ySize)
               .xScaleStep(xScaleStep)
               .yScaleStep(yScaleStep)
               .padding(30)
               .build();
        return configuration;
    }
}
